//专门请求数据的装饰器方法
import $ from 'jquery';
import { ITodoData } from '../typings.ts';

/**
 * 自定义装饰器：
 * 新增请求数据/todolist
 * @param target 使用该函数装饰器的类
 * @param methodName 使用该函数装饰器的方法名称 _init
 * @param descriptor 一个修饰符的配置对象
 */
export function getTodoList(
  target: any,
  methodName: string,
  descriptor: PropertyDescriptor
): void {
  /**
   * target参数是使用该函数装饰器的类(包含类里面的所有方法不管共有还是私有)
   * console.log(target);
   * TodoDom: {
   *   addTodo: addTodo(todo) { const _todo = this._todoData.find((item) => {…},
   *   constructor: class TodoEvent,
   *   removeTodo: removeTodo(target, id) { this._todoData = this._todoData.filter((todo) => {…},
   *   toggleComplete: toggleComplete(target, id) { this._todoData = this._todoData.map((todo) => {…},
   *   _init: ƒ _init(todoData)
   * }
   */
  // console.log(methodName);
  //打印的是使用该函数装饰器的方法名称 _init

  /**
   * console.log(descriptor);
   * 打印的是一个修饰符的配置对象
   * {
   *   configurable: true,
   *   enumerable: false,
   *   value: ƒ _init(todoData),
   *   writable: true
   * }
   */

  //保存原有的 ƒ _init(todoData)方法
  const _origin = descriptor.value;

  //重写描述符里的方法
  descriptor.value = function (todoData: ITodoData[]) {
    $.get('http://localhost:8080/todolist')
      .then((res: string) => {
        if (!res) {
          return;
        }

        todoData = JSON.parse(res);
      })
      .then(() => {
        //执行原有的方法
        //拿到请求后的数据去初始化一个todolist列表节点
        _origin.call(this, todoData);
      });
  };
}

/**
 * 自定义装饰器：
 * 新增请求删除数据
 * @param target 使用该函数装饰器的类
 * @param methodName 使用该函数装饰器的方法名称 _init
 * @param descriptor 一个修饰符的配置对象
 */
export function removeTodo(
  target: any,
  methodName: string,
  descriptor: PropertyDescriptor
): void {
  const _origin = descriptor.value;

  //重写描述符里的方法
  descriptor.value = function (target: HTMLElement, id: number) {
    $.post('http://localhost:8080/remove', { id }).then(() => {
      _origin.call(this, target, id);
    });
  };
}

/**
 * 自定义装饰器：
 * 新增请求修改数据
 * @param target 使用该函数装饰器的类
 * @param methodName 使用该函数装饰器的方法名称 _init
 * @param descriptor 一个修饰符的配置对象
 */
export function toggleTodo(
  target: any,
  methodName: string,
  descriptor: PropertyDescriptor
): void {
  const _origin = descriptor.value;

  //重写描述符里的方法
  descriptor.value = function (target: HTMLElement, id: number) {
    $.post('http://localhost:8080/toggle', { id }).then(() => {
      _origin.call(this, target, id);
    });
  };
}

/**
 * 自定义装饰器：
 * 新增请求增加数据
 * @param target 使用该函数装饰器的类
 * @param methodName 使用该函数装饰器的方法名称 _init
 * @param descriptor 一个修饰符的配置对象
 */
export function addTodo(
  target: any,
  methodName: string,
  descriptor: PropertyDescriptor
): void {
  const _origin = descriptor.value;

  //重写描述符里的方法
  descriptor.value = function (todoData: ITodoData[]) {
    $.post('http://localhost:8080/add', {
      todo: JSON.stringify(todoData)
    }).then((res) => {
      if (res.statusCode === '100') {
        alert('该项已经存在');
        return;
      }

      _origin.call(this, todoData);
    });
  };
}
